package com.cloudcc.mobile.im;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;

import com.cloudcc.cloudframe.util.LogUtils;
import com.cloudcc.mobile.AppManager;
import com.cloudcc.mobile.R;
import com.cloudcc.mobile.entity.CoworkerEntity;
import com.cloudcc.mobile.im.domain.InviteMessage;
import com.cloudcc.mobile.im.domain.InviteMessage.InviteMesageStatus;
import com.cloudcc.mobile.im.parse.UserProfileManager;
import com.cloudcc.mobile.im.receiver.CallReceiver;
import com.cloudcc.mobile.im.ui.ChatActivity;
import com.cloudcc.mobile.im.ui.VideoCallActivity;
import com.cloudcc.mobile.im.ui.VoiceCallActivity;
import com.cloudcc.mobile.im.utils.PreferenceManager;
import com.cloudcc.mobile.manager.ContactsManager;
import com.cloudcc.mobile.view.im.ConversationListActivity;
import com.cloudcc.mobile.view.main.MainUIActivity;
import com.cloudcc.mobile.view.wel.WelcomeActivity;
import com.easemob.EMCallBack;
import com.easemob.EMConnectionListener;
import com.easemob.EMError;
import com.easemob.EMEventListener;
import com.easemob.EMGroupChangeListener;
import com.easemob.EMNotifierEvent;
import com.easemob.EMValueCallBack;
import com.easemob.chat.CmdMessageBody;
import com.easemob.chat.EMChat;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMChatOptions;
import com.easemob.chat.EMContactManager;
import com.easemob.chat.EMGroup;
import com.easemob.chat.EMGroupManager;
import com.easemob.chat.EMMessage;
import com.easemob.chat.EMMessage.ChatType;
import com.easemob.chat.EMMessage.Type;
import com.easemob.chat.TextMessageBody;
import com.easemob.easeui.controller.EaseUI;
import com.easemob.easeui.controller.EaseUI.EaseSettingsProvider;
import com.easemob.easeui.controller.EaseUI.EaseUserProfileProvider;
import com.easemob.easeui.model.EaseNotifier;
import com.easemob.easeui.model.EaseNotifier.EaseNotificationInfoProvider;
import com.easemob.easeui.utils.EaseCommonUtils;
import com.easemob.easeui.utils.EaseUserUtils;
import com.easemob.exceptions.EaseMobException;
import com.easemob.util.EMLog;

/**
 * im聊天工具处理
 * 
 * @author seven
 * 
 */
public class IMHelper {
	/**
	 * 数据同步listener
	 */
	static public interface DataSyncListener {
		/**
		 * 同步完毕
		 * 
		 * @param success
		 *            true：成功同步到数据，false失败
		 */
		public void onSyncComplete(boolean success);
	}

	protected static final String TAG = "DemoHelper";

	private EaseUI easeUI;

	/**
	 * EMEventListener
	 */
	protected EMEventListener eventListener = null;


	/**
	 * 联系人管理类
	 */
	private UserProfileManager userProManager;

	private static IMHelper instance = null;

	private UserModel userModel = null;

	/**
	 * HuanXin sync groups status listener
	 */
	private List<DataSyncListener> syncGroupsListeners;
	/**
	 * HuanXin sync contacts status listener
	 */
	private List<DataSyncListener> syncContactsListeners;
	/**
	 * HuanXin sync blacklist status listener
	 */
	private List<DataSyncListener> syncBlackListListeners;

	private boolean isSyncingGroupsWithServer = false;
	private boolean isSyncingContactsWithServer = false;
	private boolean isSyncingBlackListWithServer = false;
	private boolean isGroupsSyncedWithServer = false;
	private boolean isContactsSyncedWithServer = false;
	private boolean isBlackListSyncedWithServer = false;

	private boolean alreadyNotified = false;

	public boolean isVoiceCalling;
	public boolean isVideoCalling;

	private String username;

	private Context appContext;

	private CallReceiver callReceiver;

	private EMConnectionListener connectionListener;


	private LocalBroadcastManager broadcastManager;

	private boolean isGroupAndContactListenerRegisted;

	private IMHelper() {
	}

	public synchronized static IMHelper getInstance() {
		if (instance == null) {
			instance = new IMHelper();
		}
		return instance;
	}

	/**
	 * init helper
	 * 
	 * @param context
	 *            application context
	 */
	public void init(Context context) {
		if (EaseUI.getInstance().init(context)) {
			appContext = context;
			
		    //if your app is supposed to user Google Push, please set project number
            String projectNumber = "562451699741";
            //不使用GCM推送的注释掉这行
            EMChatManager.getInstance().setGCMProjectNumber(projectNumber);
            //在小米手机上当app被kill时使用小米推送进行消息提示，同GCM一样不是必须的
            EMChatManager.getInstance().setMipushConfig("2882303761517370134", "5131737040134");
			
			// 设为调试模式，打成正式包时，最好设为false，以免消耗额外的资源
			EMChat.getInstance().setDebugMode(false);
			// get easeui instance
			easeUI = EaseUI.getInstance();
			// 调用easeui的api设置providers
			setEaseUIProviders();
			userModel = new UserModel(context);
			// 设置chat options
			setChatoptions();
			// 初始化PreferenceManager
			PreferenceManager.init(context);
			// 初始化用户管理类
			getUserProfileManager().init(context);
			// 设置全局监听
			setGlobalListeners();
			broadcastManager = LocalBroadcastManager.getInstance(appContext);
		}
	}

	/**
	 * 设置聊天的选择项
	 */
	private void setChatoptions() {
		// easeui库默认设置了一些options，可以覆盖
		EMChatOptions options = EMChatManager.getInstance().getChatOptions();
		options.allowChatroomOwnerLeave(getModel()
				.isChatroomOwnerLeaveAllowed());
		options.setRequireAck(false);//设置是否需要接受方已读确认
		options.setRequireDeliveryAck(false);//设置是否需要接受方送达确认,默认
		options.setUseRoster(false);//不使用环信的用户体系
	}

	/**
	 * 设置ui信息的提供者
	 */
	protected void setEaseUIProviders() {
		// 需要easeui库显示用户头像和昵称设置此provider
		easeUI.setUserProfileProvider(new EaseUserProfileProvider() {
			@Override
			public CoworkerEntity getUser(String username) {
				return getUserInfo(username);
			}
		});

		// 不设置，则使用easeui默认的 设置
		easeUI.setSettingsProvider(new EaseSettingsProvider() {

			@Override
			public boolean isSpeakerOpened() {
				return userModel.getSettingMsgSpeaker();
			}

			@Override
			public boolean isMsgVibrateAllowed(EMMessage message) {
				return userModel.getSettingMsgVibrate();
			}

			@Override
			public boolean isMsgSoundAllowed(EMMessage message) {
				return userModel.getSettingMsgSound();
			}

			@Override
			public boolean isMsgNotifyAllowed(EMMessage message) {
				if (message == null) {
					return userModel.getSettingMsgNotification();
				}
				if (!userModel.getSettingMsgNotification()) {
					return false;
				} else {
					return true;
				}
			}
		});
		// 离线提示消息
		// 不设置，则使用easeui默认的
		easeUI.getNotifier().setNotificationInfoProvider(
				new EaseNotificationInfoProvider() {

					@Override
					public String getTitle(EMMessage message) {
						// 修改标题,这里使用默认
						return null;
					}

					@Override
					public int getSmallIcon(EMMessage message) {
						// 设置小图标，这里为默认
						return 0;
					}

					@Override
					public String getDisplayedText(EMMessage message) {
						// 设置状态栏的消息提示，可以根据message的类型做相应提示
						String ticker = EaseCommonUtils.getMessageDigest(
								message, appContext);
						if (message.getType() == Type.TXT) {
							ticker = ticker.replaceAll("\\[.{2,3}\\]", "[表情]");
						}
						String userNick = EaseUserUtils.getUserNick(message);
						return userNick + ": " + ticker;
					}

					@Override
					public String getLatestText(EMMessage message,
							int fromUsersNum, int messageNum) {
						return null;
						// return fromUsersNum + "个基友，发来了" + messageNum + "条消息";
					}

					@Override
					public Intent getLaunchIntent(EMMessage message) {
						// 设置点击通知栏跳转事件
						Intent intent = new Intent(appContext,
								ChatActivity.class);
						// 有电话时优先跳转到通话页面
						if (isVideoCalling) {
							intent = new Intent(appContext,
									VideoCallActivity.class);
						} else if (isVoiceCalling) {
							intent = new Intent(appContext,
									VoiceCallActivity.class);
						} else {
							//普通消息的时候 首先判断是不是在前台 如果 在前台 就打开聊天页面 如果不再前台 就先打开
							boolean hasForegroundActivies = AppManager.getInstance().hasForegroundActivies();
							if (!hasForegroundActivies) {//不是前台 先进入首页
								intent =new Intent(appContext, WelcomeActivity.class);
							}
							ChatType chatType = message.getChatType();
							if (chatType == ChatType.Chat) { // 单聊信息
								intent.putExtra("userId", message.getFrom());
								intent.putExtra("chatType",
										Constant.CHATTYPE_SINGLE);
							} else { // 群聊信息
								// message.getTo()为群聊id
								intent.putExtra("userId", message.getTo());
								if (chatType == ChatType.GroupChat) {
									intent.putExtra("chatType",
											Constant.CHATTYPE_GROUP);
								} else {
									intent.putExtra("chatType",
											Constant.CHATTYPE_CHATROOM);
								}

							}
						}
						return intent;
					}
				});
	}

	/**
	 * 设置全局事件监听
	 */
	protected void setGlobalListeners() {
		syncGroupsListeners = new ArrayList<DataSyncListener>();
		syncContactsListeners = new ArrayList<DataSyncListener>();
		syncBlackListListeners = new ArrayList<DataSyncListener>();

		isGroupsSyncedWithServer = userModel.isGroupsSynced();
		isContactsSyncedWithServer = userModel.isContactSynced();
		isBlackListSyncedWithServer = userModel.isBacklistSynced();

		// create the global connection listener
		connectionListener = new EMConnectionListener() {
			@Override
			public void onDisconnected(int error) {
				LogUtils.d("imchat", "服务器断开了:"+error);
				if (error == EMError.USER_REMOVED) {
					onCurrentAccountRemoved();
				} else if (error == EMError.CONNECTION_CONFLICT) {
					LogUtils.d("imchat", "单点登录。。。。");
					onConnectionConflict();
				}
			}

			@Override
			public void onConnected() {
				LogUtils.d("imchat", "连接上服务器了:isGroupsSyncedWithServer:"+isGroupsSyncedWithServer+" isContactsSyncedWithServer: "+isContactsSyncedWithServer);
				// in case group and contact were already synced, we supposed to
				// notify sdk we are ready to receive the events
				if (isGroupsSyncedWithServer && isContactsSyncedWithServer) {
					new Thread() {
						@Override
						public void run() {
							IMHelper.getInstance().notifyForRecevingEvents();
						}
					}.start();
				} else {
					if (!isGroupsSyncedWithServer) {
						asyncFetchGroupsFromServer(null);
					}

					if (!isContactsSyncedWithServer) {
						asyncFetchContactsFromServer(null);
					}

					//黑名单
//					if (!isBlackListSyncedWithServer) {
//						asyncFetchBlackListFromServer(null);
//					}
				}
			}
		};

		IntentFilter callFilter = new IntentFilter(EMChatManager.getInstance()
				.getIncomingCallBroadcastAction());
		if (callReceiver == null) {
			callReceiver = new CallReceiver();
		}

		// 注册通话广播接收者
		appContext.registerReceiver(callReceiver, callFilter);
		// 注册连接监听
		EMChatManager.getInstance().addConnectionListener(connectionListener);
		// 注册群组和联系人监听
		registerGroupAndContactListener();
		// 注册消息事件监听
		registerEventListener();

	}

	/**
	 * 注册群组和联系人监听，由于logout的时候会被sdk清除掉，再次登录的时候需要再注册一下
	 */
	public void registerGroupAndContactListener() {
		if (!isGroupAndContactListenerRegisted) {
			// 注册群组变动监听
			EMGroupManager.getInstance().addGroupChangeListener(
					new MyGroupChangeListener());
			isGroupAndContactListenerRegisted = true;
		}

	}

	/**
	 * 群组变动监听
	 */
	class MyGroupChangeListener implements EMGroupChangeListener {

		@Override
		public void onInvitationReceived(String groupId, String groupName,
				String inviter, String reason) {

			boolean hasGroup = false;
			for (EMGroup group : EMGroupManager.getInstance().getAllGroups()) {
				if (group.getGroupId().equals(groupId)) {
					hasGroup = true;
					break;
				}
			}
			if (!hasGroup)
				return;

			// 被邀请
			String st3 = appContext
					.getString(R.string.Invite_you_to_join_a_group_chat);
			EMMessage msg = EMMessage.createReceiveMessage(Type.TXT);
			msg.setChatType(ChatType.GroupChat);
			msg.setFrom(inviter);
			msg.setTo(groupId);
			msg.setMsgId(UUID.randomUUID().toString());
			msg.addBody(new TextMessageBody(st3));
			// 保存邀请消息
			EMChatManager.getInstance().saveMessage(msg);
			// 提醒新消息
			getNotifier().viberateAndPlayTone(msg);
			// 发送local广播
			broadcastManager.sendBroadcast(new Intent(
					Constant.ACTION_GROUP_CHANAGED));
		}

		@Override
		public void onInvitationAccpted(String groupId, String inviter,
				String reason) {
		}

		@Override
		public void onInvitationDeclined(String groupId, String invitee,
				String reason) {
		}

		@Override
		public void onUserRemoved(String groupId, String groupName) {
			// TODO 提示用户被T了，demo省略此步骤
			broadcastManager.sendBroadcast(new Intent(
					Constant.ACTION_GROUP_CHANAGED));
		}

		@Override
		public void onGroupDestroy(String groupId, String groupName) {
			// 群被解散
			// TODO 提示用户群被解散,demo省略
			broadcastManager.sendBroadcast(new Intent(
					Constant.ACTION_GROUP_CHANAGED));
		}

		@Override
		public void onApplicationReceived(String groupId, String groupName,
				String applyer, String reason) {

			// 用户申请加入群聊
			InviteMessage msg = new InviteMessage();
			msg.setFrom(applyer);
			msg.setTime(System.currentTimeMillis());
			msg.setGroupId(groupId);
			msg.setGroupName(groupName);
			msg.setReason(reason);
			Log.d(TAG, applyer + " 申请加入群聊：" + groupName);
			msg.setStatus(InviteMesageStatus.BEAPPLYED);
			notifyNewIviteMessage(msg);
			broadcastManager.sendBroadcast(new Intent(
					Constant.ACTION_GROUP_CHANAGED));
		}

		@Override
		public void onApplicationAccept(String groupId, String groupName,
				String accepter) {

			String st4 = appContext
					.getString(R.string.Agreed_to_your_group_chat_application);
			// 加群申请被同意
			EMMessage msg = EMMessage.createReceiveMessage(Type.TXT);
			msg.setChatType(ChatType.GroupChat);
			msg.setFrom(accepter);
			msg.setTo(groupId);
			msg.setMsgId(UUID.randomUUID().toString());
			msg.addBody(new TextMessageBody(accepter + " " + st4));
			// 保存同意消息
			EMChatManager.getInstance().saveMessage(msg);
			// 提醒新消息
			getNotifier().viberateAndPlayTone(msg);
			broadcastManager.sendBroadcast(new Intent(
					Constant.ACTION_GROUP_CHANAGED));
		}

		@Override
		public void onApplicationDeclined(String groupId, String groupName,
				String decliner, String reason) {
			// 加群申请被拒绝，demo未实现
		}
	}


	/**
	 * 保存并提示消息的邀请消息
	 * 
	 * @param msg
	 */
	private void notifyNewIviteMessage(InviteMessage msg) {
		// 提示有新消息
		getNotifier().viberateAndPlayTone(null);
	}

	/**
	 * 账号在别的设备登录
	 */
	protected void onConnectionConflict() {
		Intent intent = new Intent(appContext, ConversationListActivity.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.putExtra(Constant.ACCOUNT_CONFLICT, true);
		appContext.startActivity(intent);
	}

	/**TODO IM 修改
	 * 账号被移除的时候 
	 */
	protected void onCurrentAccountRemoved() {
		Intent intent = new Intent(appContext, MainUIActivity.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.putExtra(Constant.ACCOUNT_REMOVED, true);
		appContext.startActivity(intent);
	}

	private CoworkerEntity getUserInfo(String hxUserName) {
		// 获取user信息，demo是从内存的好友列表里获取，
		// 实际开发中，可能还需要从服务器获取用户信息,
		// 从服务器获取的数据，最好缓存起来，避免频繁的网络请求
		CoworkerEntity user = null;
		// if(username.equals(EMChatManager.getInstance().getCurrentUser()))
		// return getUserProfileManager().getCurrentUserInfo();
		user = ContactsManager.getInstance().getUserInfoByHXId(hxUserName);
		// TODO 获取不在好友列表里的群成员具体信息，即陌生人信息，demo未实现
		// if(user == null && getRobotList() != null){
		// user = getRobotList().get(username);
		// }
		//如果获得的为空 就去同步通讯录
		return user;
	}

	/**
	 * 全局事件监听 因为可能会有UI页面先处理到这个消息，所以一般如果UI页面已经处理，这里就不需要再次处理 activityList.size()
	 * <= 0 意味着所有页面都已经在后台运行，或者已经离开Activity Stack
	 */
	protected void registerEventListener() {
		eventListener = new EMEventListener() {
			private BroadcastReceiver broadCastReceiver = null;

			@Override
			public void onEvent(EMNotifierEvent event) {
				LogUtils.d("imchat", "收到消息,是否在前台"+easeUI.hasForegroundActivies());
				
				EMMessage message = null;
				if (event.getData() instanceof EMMessage) {
					message = (EMMessage) event.getData();
					EMLog.d(TAG, "receive the event : " + event.getEvent()
							+ ",id : " + message.getMsgId());
				}

				switch (event.getEvent()) {
				case EventNewMessage:
					// 应用在后台，不需要刷新UI,通知栏提示新消息
					
					if (!easeUI.hasForegroundActivies()) {
						getNotifier().onNewMsg(message);
					}
					break;
				case EventOfflineMessage:
					if (!easeUI.hasForegroundActivies()) {
						EMLog.d(TAG, "received offline messages");
						List<EMMessage> messages = (List<EMMessage>) event
								.getData();
						getNotifier().onNewMesg(messages);
					}
					break;
				// below is just giving a example to show a cmd toast, the app
				// should not follow this
				// so be careful of this
				case EventNewCMDMessage: {

					EMLog.d(TAG, "收到透传消息");
					// 获取消息body
					CmdMessageBody cmdMsgBody = (CmdMessageBody) message
							.getBody();
					final String action = cmdMsgBody.action;// 获取自定义action

					// 获取扩展属性 此处省略
					// message.getStringAttribute("");
					EMLog.d(TAG, String.format("透传消息：action:%s,message:%s",
							action, message.toString()));
					final String str = appContext
							.getString(R.string.receive_the_passthrough);

					final String CMD_TOAST_BROADCAST = "easemob.demo.cmd.toast";
					IntentFilter cmdFilter = new IntentFilter(
							CMD_TOAST_BROADCAST);

					if (broadCastReceiver == null) {
						broadCastReceiver = new BroadcastReceiver() {

							@Override
							public void onReceive(Context context, Intent intent) {
								// TODO Auto-generated method stub
								Toast.makeText(appContext,
										intent.getStringExtra("cmd_value"),
										Toast.LENGTH_SHORT).show();
							}
						};

						// 注册广播接收者
						appContext.registerReceiver(broadCastReceiver,
								cmdFilter);
					}

					Intent broadcastIntent = new Intent(CMD_TOAST_BROADCAST);
					broadcastIntent.putExtra("cmd_value", str + action);
					appContext.sendBroadcast(broadcastIntent, null);

					break;
				}
				case EventDeliveryAck:
					message.setDelivered(true);
					break;
				case EventReadAck:
					message.setAcked(true);
					break;
				// add other events in case you are interested in
				default:
					break;
				}

			}
		};

		EMChatManager.getInstance().registerEventListener(eventListener);
	}

	/**
	 * 是否登录成功过
	 * 
	 * @return
	 */
	public boolean isLoggedIn() {
		return EMChat.getInstance().isLoggedIn();
	}

	/**
	 * 退出登录
	 * 
	 * @param unbindDeviceToken
	 *            是否解绑设备token(使用GCM才有)
	 * @param callback
	 *            callback
	 */
	public void logout(boolean unbindDeviceToken, final EMCallBack callback) {
		endCall();
		EMChatManager.getInstance().logout(unbindDeviceToken, new EMCallBack() {

			@Override
			public void onSuccess() {
				reset();
				if (callback != null) {
					callback.onSuccess();
				}

			}

			@Override
			public void onProgress(int progress, String status) {
				if (callback != null) {
					callback.onProgress(progress, status);
				}
			}

			@Override
			public void onError(int code, String error) {
				if (callback != null) {
					callback.onError(code, error);
				}
			}
		});
	}

	/**
	 * 获取消息通知类
	 * 
	 * @return
	 */
	public EaseNotifier getNotifier() {
		return easeUI.getNotifier();
	}

	public UserModel getModel() {
		return (UserModel) userModel;
	}

	/**
	 * 获取好友list
	 * 
	 * @return
	 */
	public Map<String, CoworkerEntity> getContactList() {
		return ContactsManager.getInstance().getContactList();
	}

	/**
	 * 设置当前用户的环信id
	 * 
	 * @param username
	 */
	public void setCurrentUserName(String username) {
		this.username = username;
		userModel.setCurrentUserName(username);
	}
	/**
	 * 获取当前用户的环信id
	 */
	public String getCurrentUsernName() {
		if (username == null) {
			username = userModel.getCurrentUsernName();
		}
		return username;
	}

	public UserProfileManager getUserProfileManager() {
		if (userProManager == null) {
			userProManager = new UserProfileManager();
		}
		return userProManager;
	}

	void endCall() {
		try {
			EMChatManager.getInstance().endCall();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void addSyncGroupListener(DataSyncListener listener) {
		if (listener == null) {
			return;
		}
		if (!syncGroupsListeners.contains(listener)) {
			syncGroupsListeners.add(listener);
		}
	}

	public void removeSyncGroupListener(DataSyncListener listener) {
		if (listener == null) {
			return;
		}
		if (syncGroupsListeners.contains(listener)) {
			syncGroupsListeners.remove(listener);
		}
	}

	public void addSyncContactListener(DataSyncListener listener) {
		if (listener == null) {
			return;
		}
		if (!syncContactsListeners.contains(listener)) {
			syncContactsListeners.add(listener);
		}
	}

	public void removeSyncContactListener(DataSyncListener listener) {
		if (listener == null) {
			return;
		}
		if (syncContactsListeners.contains(listener)) {
			syncContactsListeners.remove(listener);
		}
	}

	public void addSyncBlackListListener(DataSyncListener listener) {
		if (listener == null) {
			return;
		}
		if (!syncBlackListListeners.contains(listener)) {
			syncBlackListListeners.add(listener);
		}
	}

	public void removeSyncBlackListListener(DataSyncListener listener) {
		if (listener == null) {
			return;
		}
		if (syncBlackListListeners.contains(listener)) {
			syncBlackListListeners.remove(listener);
		}
	}

	/**
	 * 同步操作，从服务器获取群组列表 该方法会记录更新状态，可以通过isSyncingGroupsFromServer获取是否正在更新
	 * 和isGroupsSyncedWithServer获取是否更新已经完成
	 * 
	 * @throws EaseMobException
	 */
	public synchronized void asyncFetchGroupsFromServer(
			final EMCallBack callback) {
		if (isSyncingGroupsWithServer) {
			return;
		}

		isSyncingGroupsWithServer = true;

		new Thread() {
			@Override
			public void run() {
				try {
					EMGroupManager.getInstance().getGroupsFromServer();

					// in case that logout already before server returns, we
					// should return immediately
					if (!EMChat.getInstance().isLoggedIn()) {
						return;
					}

					userModel.setGroupsSynced(true);

					isGroupsSyncedWithServer = true;
					isSyncingGroupsWithServer = false;

					// 通知listener同步群组完毕
					noitifyGroupSyncListeners(true);
					if (isContactsSyncedWithServer()) {
						notifyForRecevingEvents();
					}
					if (callback != null) {
						callback.onSuccess();
					}
				} catch (EaseMobException e) {
					userModel.setGroupsSynced(false);
					isGroupsSyncedWithServer = false;
					isSyncingGroupsWithServer = false;
					noitifyGroupSyncListeners(false);
					if (callback != null) {
						callback.onError(e.getErrorCode(), e.toString());
					}
				}

			}
		}.start();
	}

	public void noitifyGroupSyncListeners(boolean success) {
		for (DataSyncListener listener : syncGroupsListeners) {
			listener.onSyncComplete(success);
		}
	}

	public void asyncFetchContactsFromServer(
			final EMValueCallBack<List<String>> callback) {
		LogUtils.d("imchat", "环信同步联系人");
		if (isSyncingContactsWithServer) {
			return;
		}

		isSyncingContactsWithServer = true;

		new Thread() {
			@Override
			public void run() {
				List<String> usernames = null;
				try {
					usernames = EMContactManager.getInstance()
							.getContactUserNames();
					// in case that logout already before server returns, we
					// should return immediately
					if (!EMChat.getInstance().isLoggedIn()) {
						return;
					}

					Map<String, CoworkerEntity> userlist = new HashMap<String, CoworkerEntity>();
					for (String username : usernames) {
						CoworkerEntity user = new CoworkerEntity();
						// EaseCommonUtils.setUserInitialLetter(user);
						userlist.put(username, user);
					}
					// 存入内存
					getContactList().clear();
					getContactList().putAll(userlist);
					// 存入db
					//UserDao dao = new UserDao(appContext);
					List<CoworkerEntity> users = new ArrayList<CoworkerEntity>(
							userlist.values());
					// dao.saveContactList(users);

					userModel.setContactSynced(true);
					EMLog.d(TAG, "set contact syn status to true");

					isContactsSyncedWithServer = true;
					isSyncingContactsWithServer = false;

					// 通知listeners联系人同步完毕
					notifyContactsSyncListener(true);
					if (isGroupsSyncedWithServer()) {
						notifyForRecevingEvents();
					}

					// test
					// getUserProfileManager().asyncFetchContactInfosFromServer(usernames,new
					// EMValueCallBack<List<SortModel>>() {
					//
					// @Override
					// public void onSuccess(List<SortModel> uList) {
					// updateContactList(uList);
					// getUserProfileManager().notifyContactInfosSyncListener(true);
					// }
					//
					// @Override
					// public void onError(int error, String errorMsg) {
					// }
					// });
					if (callback != null) {
						callback.onSuccess(usernames);
					}
				} catch (EaseMobException e) {
					userModel.setContactSynced(false);
					isContactsSyncedWithServer = false;
					isSyncingContactsWithServer = false;
					noitifyGroupSyncListeners(false);
					e.printStackTrace();
					if (callback != null) {
						callback.onError(e.getErrorCode(), e.toString());
					}
				}

			}
		}.start();
	}

	public void notifyContactsSyncListener(boolean success) {
		for (DataSyncListener listener : syncContactsListeners) {
			listener.onSyncComplete(success);
		}
	}

	public void asyncFetchBlackListFromServer(
			final EMValueCallBack<List<String>> callback) {

		if (isSyncingBlackListWithServer) {
			return;
		}

		isSyncingBlackListWithServer = true;

		new Thread() {
			@Override
			public void run() {
				try {
					List<String> usernames = EMContactManager.getInstance()
							.getBlackListUsernamesFromServer();

					// in case that logout already before server returns, we
					// should return immediately
					if (!EMChat.getInstance().isLoggedIn()) {
						return;
					}

					userModel.setBlacklistSynced(true);

					isBlackListSyncedWithServer = true;
					isSyncingBlackListWithServer = false;

					EMContactManager.getInstance().saveBlackList(usernames);
					notifyBlackListSyncListener(true);
					if (callback != null) {
						callback.onSuccess(usernames);
					}
				} catch (EaseMobException e) {
					userModel.setBlacklistSynced(false);

					isBlackListSyncedWithServer = false;
					isSyncingBlackListWithServer = true;
					e.printStackTrace();

					if (callback != null) {
						callback.onError(e.getErrorCode(), e.toString());
					}
				}

			}
		}.start();
	}

	public void notifyBlackListSyncListener(boolean success) {
		for (DataSyncListener listener : syncBlackListListeners) {
			listener.onSyncComplete(success);
		}
	}

	public boolean isSyncingGroupsWithServer() {
		return isSyncingGroupsWithServer;
	}

	public boolean isSyncingContactsWithServer() {
		return isSyncingContactsWithServer;
	}

	public boolean isSyncingBlackListWithServer() {
		return isSyncingBlackListWithServer;
	}

	public boolean isGroupsSyncedWithServer() {
		return isGroupsSyncedWithServer;
	}

	public boolean isContactsSyncedWithServer() {
		return isContactsSyncedWithServer;
	}

	public boolean isBlackListSyncedWithServer() {
		return isBlackListSyncedWithServer;
	}

	public synchronized void notifyForRecevingEvents() {
		if (alreadyNotified) {
			return;
		}
		// 通知sdk，UI 已经初始化完毕，注册了相应的receiver和listener, 可以接受broadcast了
		EMChat.getInstance().setAppInited();
		alreadyNotified = true;
	}

	synchronized void reset() {
		isSyncingGroupsWithServer = false;
		isSyncingContactsWithServer = false;
		isSyncingBlackListWithServer = false;

		userModel.setGroupsSynced(false);
		userModel.setContactSynced(false);
		userModel.setBlacklistSynced(false);

		isGroupsSyncedWithServer = false;
		isContactsSyncedWithServer = false;
		isBlackListSyncedWithServer = false;

		alreadyNotified = false;
		isGroupAndContactListenerRegisted = false;

		getUserProfileManager().reset();
	}

	public void pushActivity(Activity activity) {
		easeUI.pushActivity(activity);
	}

	public void popActivity(Activity activity) {
		easeUI.popActivity(activity);
	}

}
